package com.aw.baselib.net.api

import com.aw.baselib.R
import com.aw.baselib.base.AwBaseApplication
import com.aw.baselib.base.AwBaseConstant
import com.aw.baselib.net.RequestBase
import com.aw.baselib.net.SSLSocketClient
import com.aw.baselib.util.AwDataUtil.isEmpty
import com.aw.baselib.util.AwLog
import com.aw.baselib.util.AwLog.d
import okhttp3.Cache
import okhttp3.Call
import okhttp3.Callback
import okhttp3.Interceptor
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.RequestBody
import okhttp3.Response
import okhttp3.logging.HttpLoggingInterceptor
import java.io.File
import java.io.IOException
import java.io.InterruptedIOException
import java.util.concurrent.TimeUnit

/**
 * @author : hzw
 */
object Okhttp3Manager {
    /** 网络请求重试，请求时间间隔  */
    const val NET_RETRY_INTERVAL: Long = 500

    //设置缓存目录
    private val cacheDirectory =
        File(AwBaseApplication.instance?.applicationContext?.cacheDir?.absolutePath, "MyCache")
    private val cache = Cache(cacheDirectory, (10 * 1024 * 1024).toLong())
    val okhttp: OkHttpClient.Builder
        get() {
            val requestParamInterceptor = UrlInterceptor()
            val httpClient = OkHttpClient.Builder()
            httpClient.connectTimeout(60, TimeUnit.SECONDS)
            httpClient.readTimeout(60, TimeUnit.SECONDS)
            httpClient.writeTimeout(60, TimeUnit.SECONDS)
            //        httpClient.retryOnConnectionFailure(true);
            httpClient.addInterceptor(logging())
            httpClient.addInterceptor(RetryInterceptor())
            httpClient.addNetworkInterceptor(requestParamInterceptor)
            httpClient.sslSocketFactory(SSLSocketClient.sSLSocketFactory)
            httpClient.hostnameVerifier(SSLSocketClient.hostnameVerifier)
            httpClient.cache(cache) //设置缓存
            //加入拦截器
            //        RequestParamInterceptor requestParamInterceptor = new RequestParamInterceptor();
            //        httpClient.addNetworkInterceptor(requestParamInterceptor);
            //加入https的证书
            /*      int[] certficates = new int[]{R.raw.app_key};
        SSLSocketFactory sslSocketFactory = getSSLSocketFactory(AppContext.getContext(), certficates);
        if (sslSocketFactory != null) {
            httpClient.sslSocketFactory(sslSocketFactory);
        }
*/return httpClient
        }

    //OKHttpClient 请求库的日志管理配置
    private fun logging(): Interceptor {
        val logging = HttpLoggingInterceptor { message: String? -> d("okhttp", message) }
        logging.level = HttpLoggingInterceptor.Level.BODY
        if (AwLog.is_Loggable) {
            logging.level = HttpLoggingInterceptor.Level.BODY
        } else {
            logging.level = HttpLoggingInterceptor.Level.NONE
        }
        return logging
    }

    fun getRequest(url: String?, callback: OkhttpCallback) {
        val request =
            Request.Builder() //                .cacheControl(CacheControl.FORCE_NETWORK) //取消缓存读取
                .method("GET", null)
                .url(url)
                .build()
        val mcall = okhttp.build().newCall(request)
        mcall.enqueue(object : Callback {
            override fun onFailure(call: Call, e: IOException) {
                d("getRequest onFailure........")
                if (isEmpty(e.message)) {
                    callback.onFail(
                        AwBaseApplication.instance?.getString(R.string.common_net_server_abnormal)
                    )
                } else {
                    callback.onFail(e.message)
                }
            }

            override fun onResponse(call: Call, response: Response) {
                d("getRequest onResponse........")
                if (response.isSuccessful) {
                    try {
                        callback.onSuccess(response.body()!!.string())
                    } catch (e: IOException) {
                        e.printStackTrace()
                        callback.onFail("response parse exception")
                    }
                } else {
                    callback.onFail(
                        AwBaseApplication.instance?.getString(R.string.common_net_server_abnormal)
                    )
                }
            }
        })
    }

    fun postRequest(url: String?, body: RequestBody?, callback: OkhttpCallback) {
        var body = body
        if (body == null) {
            body = RequestBase.body
        }
        val request = Request.Builder()
            .url(url)
            .post(body)
            .build()
        val call = okhttp.build().newCall(request)
        call.enqueue(object : Callback {
            override fun onFailure(call: Call, e: IOException) {
                d("getRequest onFailure........")
                callback.onFail(e.message)
            }

            override fun onResponse(call: Call, response: Response) {
                d("postRequest onResponse........")
                if (response.isSuccessful) {
                    try {
                        callback.onSuccess(response.body()!!.string())
                    } catch (e: IOException) {
                        e.printStackTrace()
                        callback.onFail(e.message)
                    }
                } else {
                    callback.onFail(
                        AwBaseApplication.instance?.getString(R.string.common_net_server_abnormal)
                    )
                }
            }
        })
    }

    /**
     * @Desc   重试 拦截器，默认所有白名单外的网络请求，全部重试3次
     * @parame
     * @return
     */
    private class RetryInterceptor : Interceptor {
        @Throws(IOException::class)
        override fun intercept(chain: Interceptor.Chain): Response {
            val request = chain.request()
            var response = doRequest(chain, request)!!
            var retryNum = 0
            //判断请求路径是否在过滤清单中，如果在，则直接返回相应，不做重试请求处理
            if (AwBaseConstant.NET_RETRY_FILTER_LIST.size > 0) {
                for (urlFilter in AwBaseConstant.NET_RETRY_FILTER_LIST) {
                    if (request != null && request.url().url().toString().contains(urlFilter!!)) {
                        return response
                    }
                }
            }
            //默认循环请求3次，成功即终止
            while ((response == null || !response.isSuccessful) && retryNum < AwBaseConstant.NET_REQUEST_MAX_RETRY_COUNT) {
                try {
                    d("属于网络异常，重试中，第" + retryNum + "次")
                    Thread.sleep(NET_RETRY_INTERVAL)
                } catch (e: InterruptedException) {
                    Thread.currentThread().interrupt()
                    throw InterruptedIOException()
                }
                retryNum++
                // retry the request
                response = doRequest(chain, request)!!
            }
            return response
        }

        private fun doRequest(chain: Interceptor.Chain, request: Request?): Response? {
            var response: Response? = null
            try {
                response = chain.proceed(request)
            } catch (e: Exception) {
            }
            return response
        }
    }

    interface OkhttpCallback {
        fun onSuccess(str: String?)
        fun onFail(msg: String?)
    }
}